<template>
  <section class="treeBlock">
    <div class="searchBox">
      <a-input v-model="searchVal" placeholder="请输入搜索内容" @change="handleSearch">
        <template slot="addonAfter">
          <a-popover placement="bottomRight">
            <template slot="content">
              <p style="cursor: pointer;" @click="() => (this.expandedKeys = this.allIds)">展开全部</p>
              <span style="cursor: pointer;" @click="() => (this.expandedKeys = [])">折叠全部</span>
            </template>
            <a-icon type="menu-unfold" />
          </a-popover>
        </template>
      </a-input>
    </div>
    <div class="treeBox">
      <a-tree
        ref="tree"
        :checkable="this.leftTreeConfig.isSelection?true:false"
        :replaceFields="{
          title: 'name',
          key: 'id',
          value:'id',
          children: 'chrildens'
        }"
        :treeData="treeData"
        :expandedKeys.sync="expandedKeys"
        :selectedKeys="selectedKeys"
        :checkedKeys="checkedKeys"
        @select="handleSelect"
        @check="handleCheck"
      >
        <template slot="title" slot-scope="{ name }">
          <span v-if="name.indexOf(searchVal) > -1">
            {{ name.substr(0, name.indexOf(searchVal)) }}
            <span style="color: #f50">{{ searchVal }}</span>
            {{ name.substr(name.indexOf(searchVal) + searchVal.length) }}
          </span>
          <span v-else>{{ name }}</span>
        </template>
      </a-tree>
    </div>
  </section>
</template>

<script>
// import * as api from '@/api/api';
// import Button from '@/components/typicalControl/button';
export default {
  name: 'TypicalLeftTree',
  // components: {
  //   Button: Button
  // },
  props: {
    leftTreeConfig: {
      type: Object,
      default: () => {
        return {
          // 默认组织机构树
          treeType: 'organization',
          // 组织和部门混合树
          // treeType: 'organizationDepartment',
          // isSelection: true,
          treeData: []
        };
      }
    }
  },
  data() {
    return {
      searchVal: '',
      // 展开指定的树节点双向绑定值
      expandedKeys: [],
      selectedKeys: [],
      checkedKeys: [],
      choiceData: {},
      allIds: [],
      treeData: [],
      isLoaded: false
    };
  },
  computed: {
    watchTreeData: function() {
      return this.leftTreeConfig.treeData;
    }
  },
  watch: {
    watchTreeData: {
      handler: function() {
        this.manualUpdate();
      },
      immediate: true
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    // 20211229z 树形数据接口外置，组件自行监听数据异步加载后初始化
    // /**
    //  * [getTreeData 获取组织列表树形结构数据]
    //  * @return {[type]} [description]
    //  */
    // getTreeData() {
    //   api.organizationsTree().then(res => {
    //     // if (res.code === 200) {
    //     //   this.treeData = res.data;
    //     // }
    //     this.InitializationManage();
    //     this.onlyLoad();
    //   });
    // },
    /**
     * [manualUpdate 配置里treeData异步更新，手动更新]
     * @param  {Boolean} isLoaded [是否强制全部更新]
     * @return {[type]}           [description]
     */
    manualUpdate(isLoaded) {
      if (isLoaded) {
        this.isLoaded = false;
      }
      if (!this.isLoaded && this.leftTreeConfig.treeData.length > 0) {
        this.InitializationManage();
      }
    },
    /**
     * [setTreeSelected 设置选中的label]
     * @param {[arr]} val [description]
     */
    setTreeSelected(val) {
      this.selectedKeys = val;
    },
    /**
     * [setChecked 设置选中的勾选框]
     * @param {[arr]} val [description]
     */
    setChecked(val) {
      this.checkedKeys = val;
      this.searchVal = '';
    },
    /**
     * [InitializationManage 初始化树形数据管理]
     */
    InitializationManage() {
      if (this.leftTreeConfig.treeData) {
        this.treeData = JSON.parse(JSON.stringify(this.leftTreeConfig.treeData));
      }
      switch (this.leftTreeConfig.treeType) {
        case 'organization':
        this._recursiveInitialization(this.treeData);
        break;
        case 'organizationDepartment':
        this._setOrganizationType(this.treeData);
        break;
        case 'permissions':
        this._setPermissionsType(this.treeData);
        break;
        default:
        this._recursiveInitialization(this.treeData);
      };
      this.onlyLoad();
    },
    /**
     * [_setOrganizationType 设置组织的type]
     * @param {[type]} organizationData [设置范围数组]
     * @param {[type]} parent           [父级]
     */
    _setOrganizationType(organizationData, parent) {
      organizationData.forEach(item => {
        item.scopedSlots = { title: 'title' };
        item.disabled = item.isEnable === 0;
        item.type = '_organization';
        if (parent) {
          item.parent = parent;
        }
        if (item.chrildens) {
          this._setOrganizationType(item.chrildens, item);
        }
        if (item.departments) {
          if (!item.chrildens) item.chrildens = [];
          this._setDepartmentType(item.departments, item);
          item.departments.forEach(value => {
            item.chrildens.push(value);
          });
        }
      });
    },
    /**
     * [_setDepartmentType 设置部门的type]
     * @param {[type]} departmentsData [设置范围数组]
     * @param {[type]} parent          [父级]
     */
    _setDepartmentType(departmentsData, parent) {
      departmentsData.forEach(value => {
        value.type = '_department';
        value.scopedSlots = { title: 'title' };
        value.disabled = value.isEnable === 0;
        if (parent) {
          value.parent = parent;
        }
        if (value.chrildens) {
          this._setDepartmentType(value.chrildens, value);
        }
      });
    },
    /**
     * [getAllIds 生成全部展开的id]
     * @return {[type]}     [description]
     */
    getAllIds() {
      this.allIds = [];
      for (var i = 0; i < this.treeData.length; i++) {
        this._recursiveAddAllIds(this.treeData[i]);
      }
    },
    /**
     * [onlyLoad 仅一次初始化的数据]
     */
    onlyLoad() {
      if (!this.isLoaded) {
        this.isLoaded = true;
        const val = [];
        val.push(this.treeData[0].id);
        this.setTreeSelected(val);
        this.getAllIds();
        this.expandedKeys = this.allIds;
      }
    },
    /**
     * [_recursiveAddAllIds 递归树型数据对象添加到数组]
     * @param  {[type]} obj [树型数据对象]
     * @return {[type]}     [description]
     */
    _recursiveAddAllIds(obj) {
      if (obj.chrildens) {
        this.allIds.push(obj.id);
        for (var i = 0; i < obj.chrildens.length; i++) {
          this._recursiveAddAllIds(obj.chrildens[i]);
        }
      }
    },
    /**
     * [_recursiveInitialization 递归treeData数据添加组件绑定属性]
     */
    _recursiveInitialization(treeData) {
      treeData.forEach(item => {
        item.scopedSlots = { title: 'title' };
        item.disabled = item.isEnable === 0;
        if (item.chrildens) {
          this._recursiveInitialization(item.chrildens);
        }
      });
    },
    /**
     * [_setPermissionsType 递归权限菜单treeData]
     */
    _setPermissionsType(treeData) {
      var item;
      for (var i = treeData.length - 1; i >= 0; i--) {
        item = treeData[i];
        if (item.type === 2) {
          treeData.splice(i, 1);
        } else {
          item.scopedSlots = { title: 'title' };
          item.disabled = item.isEnable === 0;
          if (item.chrildens) {
            this._recursiveInitialization(item.chrildens);
          }
        }
      }
    },
    /**
     * [handleSearch 搜索条件变化时，匹配树形数据]
     * @return {[type]} [description]
     */
    handleSearch() {
      const oResult = this._recursiveSearch(this.treeData, { aMatchid: [], aParentId: [] }, []);
      this.expandedKeys = oResult.aParentId;
    },
    /**
     * [_recursiveSearch 递归搜索匹配字段]
     * @param  {[type]} aRange        [搜索范围]
     * @param  {[type]} aResult       [结果存储]
     * @param  {[type]} aUndetermined [待定的父级id]
     * @return {[type]}               [description]
     */
    _recursiveSearch(aRange, aResult, aUndetermined) {
      for (let i = 0; i < aRange.length; i++) {
        if (aRange[i].name.indexOf(this.searchVal) !== -1) {
          aResult.aMatchid.push(aRange[i].id);
          aResult.aParentId = aResult.aParentId.concat(aUndetermined);
        }
        if (aRange[i].chrildens) {
          // 防止其他递归公用内存写入
          const _aUndetermined = JSON.parse(JSON.stringify(aUndetermined));
          _aUndetermined.push(aRange[i].id);
          this._recursiveSearch(aRange[i].chrildens, aResult, _aUndetermined);
        }
      }
      return aResult;
    },
    /**
     * [handleSelect 点击选项label]
     * @param  {[type]} selectedKeys [选中id]
     * @param  {[type]} e            [e]
     * @return {[type]}              [description]
     */
    handleSelect(selectedKeys, e) {
      if (selectedKeys.length > 0) {
        this.setTreeSelected(selectedKeys);
        this.choiceData = e.selectedNodes[0].data.props.dataRef;
      }
      // console.log('select', this.choiceData);
      // 输出选中label对象
      this.$emit('select', this.choiceData);
    },
    /**
     * [handleCheck 多选勾选变化]
     * @param  {[type]} selectedKeys [勾选的id数组（不含父级）]
     * @param  {[type]} e            [e]
     * @return {[type]}              [description]
     */
    handleCheck(selectedKeys, e) {
      this.setChecked(selectedKeys);
      let halfCheckedKeys=e.halfCheckedKeys;
      // console.log('selectionChange', selectedKeys, e);
      this.$emit('selectionChange', selectedKeys.concat(halfCheckedKeys));
      // this.$emit('selectionChange', selectedKeys);
    }
  },
  destroyed() {
  }
};
</script>

<style scoped>
  .treeBlock{
    height: 100%;
  }
  .searchBox{
    padding: 0 10px 10px;
  }
  .treeBox{
    /*预留左侧勾选框挤右边title*/
    padding: 0 30px 0 10px;
    height: calc(100% - 45px);
    overflow: auto;
  }
  .treeBox /deep/ .ant-tree li .ant-tree-node-content-wrapper {
    /*max-width: 100%;*/
    width: calc(100% - 20px);
    display: inline-block;
    height: 24px;
    margin: 0;
    /*padding: 0 5px;*/
    padding: 0;
    color: rgba(0, 0, 0, 0.65);
    line-height: 24px;
    text-decoration: none;
    vertical-align: top;
    border-radius: 2px;
    cursor: pointer;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
</style>
